package com.sz.app.customer.api;

import com.sz.biz.app.web.security.Des;
import com.sz.biz.common.utils.PassWordCreate;
import com.sz.biz.common.customer.entity.CusCustomer;
import com.sz.biz.common.customer.entity.CusUser;
import com.sz.biz.common.customer.entity.CusUserConfig;
import com.sz.biz.common.customer.service.CustomerService;
import com.sz.biz.common.customer.service.CustomerUserConfigService;
import com.sz.biz.common.customer.service.CustomerUserService;
import com.sz.biz.common.customer.dto.CusUserConfigDto;
import com.sz.common.base.cache.redis.RedisPoolManager;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.exception.BizException;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.core.service.PrincipalUtils;
import com.sz.common.core.service.sms.SmsService;
import com.sz.common.core.system.dto.FileInfoDto;
import com.sz.common.core.system.dto.MenuItem;
import com.sz.common.core.system.dto.SmsBodyDto;
import com.sz.common.core.system.service.MenuService;
import com.sz.common.core.system.service.SysFileGroupService;
import com.sz.app.customer.api.system.dto.ForgetResetPswdDto;
import com.sz.app.customer.exception.ErrorCodes;
import com.sz.app.customer.api.system.dto.CusUserSimpleDto;
import com.sz.app.customer.web.security.SecurityKeys;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import redis.clients.jedis.Jedis;

import java.text.ParseException;
import java.util.List;
import java.util.Map;

/**
 * LoginedUserController <br>
 * Author: qiankun <br>
 * Date: 2017-05-11 10:07:04
 */
@RestController
@RequestMapping("${api}/u")
@Api(description = " ", tags = "001、已登录用户资源，统一在此处")
public class LoginedUserController {

    public static final String FORGET_PASSWORD = "forgetpswd";
    public static final String FORGET_RESET_PASSWORD = "forgetresetpswd";
    public static final String TRUE = "true";
    @Autowired
    private SecurityKeys securityKeys;

    @Autowired
    private CustomerUserService cusUserService;

    @Autowired
    private CustomerService customerService;
    @Autowired
    private MenuService menuService;

    @Autowired
    private CustomerUserConfigService customerUserConfigService;

    @Autowired
    private SmsService smsService;

    @Value("${sms.forgetpassword.authentication.templatecode}")
    private String smsTemplateCode;

    @Value("${sms.forgetpassword.authentication.code.timeout}")
    private int validateCodeTimeOut;

    @Value("${sms.forgetpassword.authentication.templatekey}")
    private String templateKey;
    
    @Autowired
    SysFileGroupService fileGroupService;

    @ApiOperation(value = "获取当前用户的详情", notes = "-")
    @RequestMapping(value = "/profile", method = RequestMethod.GET)
    public ResultDto getCusUserProfile() {
        int userId = PrincipalUtils.getAccountId();
        CusUserSimpleDto cusDto = new CusUserSimpleDto();
        CusUser cusUser = cusUserService.findById(userId);
        CusUserConfigDto cusUserConfigDto = customerUserConfigService.findAllConfigByUserId(userId);
        CusCustomer cusCustomer = customerService.findCustomerById(cusUser.getRefCustomerId());
        if (ObjectUtils.isEmpty(cusCustomer)) {
            throw Exceptions.bizException(ErrorCodes.ERROR_COMMON, "cusCustomer获取异常");
        }
        cusDto.setCusUserConfig(cusUserConfigDto);
        cusDto.setFullName(cusUser.getFullName());
        cusDto.setAccountName(PrincipalUtils.getAccountName());
        cusDto.setUserId(userId);
        cusDto.setUserType(cusCustomer.getUserType());
        List<FileInfoDto> attachments = fileGroupService.getFileDtosByGroupId(cusUser.getUserAvatar());
        cusDto.setFiles(attachments);
        ResultDto resultDto = new ResultDto();
        resultDto.setData(cusDto);
        return resultDto;
    }

    @ApiOperation(value = "保存用户设置", notes = "保存用户设置")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cusUserConfigDto", value = "提交的用户设置信息\r\n i18n,pageSize", required = true, dataType = "CusUserConfigDto", paramType = "body")})
    @RequestMapping(value = "/userconfig", method = {RequestMethod.POST})
    public ResultDto saveUserConfig(@RequestBody CusUserConfigDto cusUserConfigDto)
            throws BizException, ParseException {
        int cusUserId = PrincipalUtils.getAccountId();
        cusUserConfigDto.setUserId(cusUserId);
        customerUserConfigService.saveUserConfig(cusUserConfigDto);
        PrincipalUtils.getPrincipal().setPreferredLanguage(cusUserConfigDto.getI18n());
        return new ResultDto();
    }

    @ApiOperation(value = "按参数名查询用户设置的个性化参数值", notes = "按参数名查询用户设置的个性化参数值")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "paramName", value = "要查询的参数名", required = true, dataType = "string", paramType = "query")})
    @RequestMapping(value = "/userconfig/", method = {RequestMethod.GET})
    public ResultDto findByUserIdAndParamName(@RequestParam(required = true) String paramName) {
        int userId = PrincipalUtils.getAccountId();
        CusUserConfig cusUserConfig = new CusUserConfig();
        cusUserConfig.setUserId(userId);
        cusUserConfig.setParamName(paramName);
        CusUserConfig cuc = customerUserConfigService.findByUserIdAndParamName(cusUserConfig);
        ResultDto dto = new ResultDto();
        dto.setData(cuc);
        return dto;
    }

    @ApiOperation(value = "查询当前用户所有的个性化设置", notes = "查询用户所有的设置")
    @RequestMapping(value = "/userconfig", method = RequestMethod.GET)
    public ResultDto findAllConfigByUserId() throws BizException, ParseException {
        int userId = PrincipalUtils.getAccountId();
        CusUserConfigDto cucto = customerUserConfigService.findAllConfigByUserId(userId);
        ResultDto dto = new ResultDto();
        dto.setData(cucto);
        return dto;
    }

    @RequestMapping(value = "/usertree", method = {RequestMethod.GET})
    public ResultDto getCurrUserMenu() throws Exception {
        int domainId = PrincipalUtils.getDomainId();
        String language = PrincipalUtils.getLocalLanguage();
        MenuItem menuItem = menuService.getMenuTree(domainId, language, false, false);
        ResultDto result = new ResultDto();
        result.setData(menuItem);
        return result;
    }

    /**
     * 忘记密码手机异步校验接口
     */
    @ApiOperation(value = "忘记密码手机异步校验接口", notes = "忘记密码手机异步校验接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobilePhone", value = "手机号码",
                    required = true, dataType = "string", paramType = "query")})
    @RequestMapping(value = "/forgetpswd/checktelno", method = {RequestMethod.GET})
    public QResultDto checkMobilePhoneExist(@RequestParam String mobilePhone) {

        boolean isExist = cusUserService.telNoExist(mobilePhone);

        QResultDto qResultDto = new QResultDto();

        qResultDto.setData(isExist);

        return qResultDto;
    }

    /**
     * 短信发送验证码接口
     */
    @ApiOperation(value = "短信发送验证码接口", notes = "短信发送验证码接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobilePhone", value = "手机号码",
                    required = true, dataType = "string", paramType = "query")})
    @RequestMapping(value = "/forgetpswd/sendsmscode", method = {RequestMethod.GET})
    public QResultDto sendsmscode(@RequestParam String mobilePhone) {

        boolean telnoIsExist = true;
        QResultDto qResultDto = new QResultDto();

        if (cusUserService.telNoExist(mobilePhone)) {

            //生成手机验证码
            PassWordCreate pwc = new PassWordCreate();
            String validateCode = pwc.createValidateCode(6);

            //将验证码插入redis
            Jedis jedis = RedisPoolManager.getJedis();

            if (!jedis.exists(mobilePhone + FORGET_PASSWORD)) {

                jedis.set(mobilePhone + FORGET_PASSWORD, validateCode);
                jedis.expire(mobilePhone + FORGET_PASSWORD, validateCodeTimeOut);
                jedis.close();
                //组装短信内容进行发送
                SmsBodyDto smsBodyDto = new SmsBodyDto();

                String[] templateKeyArray = templateKey.split(",");

                for (int i=0; i<templateKeyArray.length; i++) {

                    smsBodyDto.getSmsTemplateKey().add(templateKeyArray[i]);
                }

                smsBodyDto.getSmsTemplateValue().add(validateCode);

                smsService.sendSms(mobilePhone, smsTemplateCode, smsBodyDto);
            } else {
                jedis.close();
                qResultDto.setErrorCode(-1);
                qResultDto.setMsg("短信验证码已经发送，请稍后再试！");
            }

        } else {

            telnoIsExist = false;
        }

        Map<String,Object> map = new HashedMap();

        map.put("telnoIsExist",telnoIsExist);

        qResultDto.setData(telnoIsExist);

        return qResultDto;
    }

    /**
     * 检查验证码
     */
    @ApiOperation(value = "检查验证码", notes = "检查验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobilePhone", value = "手机号码",
                    required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "validateCode", value = "验证码",
                    required = true, dataType = "string", paramType = "query")})
    @RequestMapping(value = "/forgetpswd/checkvalidatecode", method = {RequestMethod.GET})
    public QResultDto checkValidateCode(@RequestParam String mobilePhone, @RequestParam String validateCode) {

        boolean isSuccess = true;

        Jedis jedis = RedisPoolManager.getJedis();

        if (cusUserService.telNoExist(mobilePhone)) {

            //检查验证码
            String cacheCode = jedis.get(mobilePhone + FORGET_PASSWORD);

            if (cacheCode != null) {

                if (!cacheCode.equalsIgnoreCase(validateCode)) {

                    isSuccess = false;
                }
            } else {

                isSuccess = false;
            }

        } else {

            isSuccess = false;
        }

        if (isSuccess) {

            jedis.del(mobilePhone + FORGET_PASSWORD);

            //增加页面跳转之间的非法判断字段，存入redis中，超时则自动删除
            jedis.set(mobilePhone + "forgetresetpswd", "true");
            jedis.expire(mobilePhone + "forgetresetpswd",validateCodeTimeOut);
        }
        jedis.close();
        QResultDto qResultDto = new QResultDto();

        qResultDto.setData(isSuccess);

        return qResultDto;
    }

    /**
     *
     * 忘记密码中重新设置密码
     */
    @ApiOperation(value = "忘记密码中重新设置密码", notes = "忘记密码中重新设置密码")
    @RequestMapping(value = "/forgetpswd/resetpassword", method = {RequestMethod.PUT})
    public QResultDto resetPasswordByTelNo(@RequestBody ForgetResetPswdDto forgetResetPswdDto) throws Exception  {

        QResultDto qResultDto = new QResultDto();

        Jedis jedis = RedisPoolManager.getJedis();

        if (jedis.exists(forgetResetPswdDto.getTelNo()+ FORGET_RESET_PASSWORD)) {

            String validateRes = jedis.get(forgetResetPswdDto.getTelNo()+ FORGET_RESET_PASSWORD);
            jedis.close();
            if (validateRes != null && TRUE.equals(validateRes)) {

                CusUser cusUser = cusUserService.selectByTelNo(forgetResetPswdDto.getTelNo());

                if (cusUser != null) {

                    cusUserService.forgetPasswordForReset(cusUser.getId(),decPassword(forgetResetPswdDto.getNewPassword()),
                            decPassword(forgetResetPswdDto.getConfirmPassword()));
                }
            }

        } else {
            jedis.close();
            qResultDto.setErrorCode(-1);
            qResultDto.setMsg("非法访问此页!");
        }

        return qResultDto;
    }

    private String decPassword(String password){
        String key1 = "DAB019642892EC3231802E13447D3F52";
        String key2 = "14833CB10FAF594B0874F3494AB0946E";
        String key3 = "42099DDB28D27ADFCFD3E961BE6E08D5";
        if (org.apache.commons.lang3.StringUtils.isNotBlank(password)) {
            return Des.getDesTool().strDec(password, securityKeys.getSecurityKey1(), securityKeys.getSecurityKey2(), securityKeys.getSecurityKey3());
        }
        return password;
    }

}
